1
|
|
|
"use strict"; |
2
|
|
|
|
3
|
|
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } |
|
|
|
|
4
|
|
|
|
5
|
|
|
const O = Object; |
|
|
|
|
6
|
|
|
|
7
|
|
|
var _require = require('printable-characters'); |
8
|
|
|
|
9
|
|
|
const first = _require.first, |
10
|
|
|
strlen = _require.strlen, |
11
|
|
|
limit = (s, n) => first(s, n - 1) + '…'; |
12
|
|
|
|
13
|
|
View Code Duplication |
const asColumns = (rows, cfg_) => { |
|
|
|
|
14
|
|
|
|
15
|
|
|
const zip = (arrs, f) => arrs.reduce((a, b) => b.map((b, i) => [].concat(_toConsumableArray(a[i] || []), [b])), []).map(args => f.apply(undefined, _toConsumableArray(args))), |
16
|
|
|
|
17
|
|
|
|
18
|
|
|
/* Convert cell data to string (converting multiline text to singleline) */ |
19
|
|
|
|
20
|
|
|
cells = rows.map(r => r.map(c => c === undefined ? '' : cfg_.print(c).replace(/\n/g, '\\n'))), |
21
|
|
|
|
22
|
|
|
|
23
|
|
|
/* Compute column widths (per row) and max widths (per column) */ |
24
|
|
|
|
25
|
|
|
cellWidths = cells.map(r => r.map(strlen)), |
26
|
|
|
maxWidths = zip(cellWidths, Math.max), |
27
|
|
|
|
28
|
|
|
|
29
|
|
|
/* Default config */ |
30
|
|
|
|
31
|
|
|
cfg = O.assign({ |
32
|
|
|
delimiter: ' ', |
33
|
|
|
minColumnWidths: maxWidths.map(x => 0), |
|
|
|
|
34
|
|
|
maxTotalWidth: 0 }, cfg_), |
35
|
|
|
delimiterLength = strlen(cfg.delimiter), |
36
|
|
|
|
37
|
|
|
|
38
|
|
|
/* Project desired column widths, taking maxTotalWidth and minColumnWidths in account. */ |
39
|
|
|
|
40
|
|
|
totalWidth = maxWidths.reduce((a, b) => a + b, 0), |
41
|
|
|
relativeWidths = maxWidths.map(w => w / totalWidth), |
42
|
|
|
maxTotalWidth = cfg.maxTotalWidth - delimiterLength * (maxWidths.length - 1), |
43
|
|
|
excessWidth = Math.max(0, totalWidth - maxTotalWidth), |
44
|
|
|
computedWidths = zip([cfg.minColumnWidths, maxWidths, relativeWidths], (min, max, relative) => Math.max(min, Math.floor(max - excessWidth * relative))), |
45
|
|
|
|
46
|
|
|
|
47
|
|
|
/* This is how many symbols we should pad or cut (per column). */ |
48
|
|
|
|
49
|
|
|
restCellWidths = cellWidths.map(widths => zip([computedWidths, widths], (a, b) => a - b)); |
50
|
|
|
|
51
|
|
|
/* Perform final composition. */ |
52
|
|
|
|
53
|
|
|
return zip([cells, restCellWidths], (a, b) => zip([a, b], (str, w) => w >= 0 ? cfg.right ? ' '.repeat(w) + str : str + ' '.repeat(w) : limit(str, strlen(str) + w)).join(cfg.delimiter)); |
54
|
|
|
}; |
55
|
|
|
|
56
|
|
|
const asTable = cfg => O.assign(arr => { |
57
|
|
|
var _ref; |
58
|
|
|
|
59
|
|
|
/* Print arrays */ |
60
|
|
|
|
61
|
|
|
if (arr[0] && Array.isArray(arr[0])) return asColumns(arr, cfg).join('\n'); |
|
|
|
|
62
|
|
|
|
63
|
|
|
/* Print objects */ |
64
|
|
|
|
65
|
|
|
const colNames = [].concat(_toConsumableArray(new Set((_ref = []).concat.apply(_ref, _toConsumableArray(arr.map(O.keys)))))), |
66
|
|
|
columns = [colNames.map(cfg.title)].concat(_toConsumableArray(arr.map(o => colNames.map(key => o[key])))), |
67
|
|
|
lines = asColumns(columns, cfg); |
68
|
|
|
|
69
|
|
|
return [lines[0], cfg.dash.repeat(strlen(lines[0]))].concat(_toConsumableArray(lines.slice(1))).join('\n'); |
70
|
|
|
}, cfg, { |
71
|
|
|
|
72
|
|
|
configure: newConfig => asTable(O.assign({}, cfg, newConfig)) |
73
|
|
|
}); |
74
|
|
|
|
75
|
|
|
module.exports = asTable({ |
76
|
|
|
|
77
|
|
|
maxTotalWidth: Number.MAX_SAFE_INTEGER, |
78
|
|
|
print: String, |
79
|
|
|
title: String, |
80
|
|
|
dash: '-', |
81
|
|
|
right: false |
82
|
|
|
}); |
83
|
|
|
|
84
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,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bGUiOiJhcy10YWJsZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG5jb25zdCBPID0gT2JqZWN0XG4gICAgLCB7IGZpcnN0LCBzdHJsZW4gfSA9IHJlcXVpcmUgKCdwcmludGFibGUtY2hhcmFjdGVycycpIC8vIGhhbmRsZXMgQU5TSSBjb2RlcyBhbmQgaW52aXNpYmxlIGNoYXJhY3RlcnNcbiAgICAsIGxpbWl0ID0gKHMsIG4pID0+IChmaXJzdCAocywgbiAtIDEpICsgJ+KApicpXG5cbmNvbnN0IGFzQ29sdW1ucyA9IChyb3dzLCBjZmdfKSA9PiB7XG4gICAgXG4gICAgY29uc3RcblxuICAgICAgICB6aXAgPSAoYXJycywgZikgPT4gYXJycy5yZWR1Y2UgKChhLCBiKSA9PiBiLm1hcCAoKGIsIGkpID0+IFsuLi5hW2ldIHx8IFtdLCBiXSksIFtdKS5tYXAgKGFyZ3MgPT4gZiAoLi4uYXJncykpLFxuXG4gICAgLyogIENvbnZlcnQgY2VsbCBkYXRhIHRvIHN0cmluZyAoY29udmVydGluZyBtdWx0aWxpbmUgdGV4dCB0byBzaW5nbGVsaW5lKSAqL1xuXG4gICAgICAgIGNlbGxzICAgICAgICAgICA9IHJvd3MubWFwIChyID0+IHIubWFwIChjID0+IChjID09PSB1bmRlZmluZWQpID8gJycgOiBjZmdfLnByaW50IChjKS5yZXBsYWNlICgvXFxuL2csICdcXFxcbicpKSksXG5cbiAgICAvKiAgQ29tcHV0ZSBjb2x1bW4gd2lkdGhzIChwZXIgcm93KSBhbmQgbWF4IHdpZHRocyAocGVyIGNvbHVtbikgICAgICovXG5cbiAgICAgICAgY2VsbFdpZHRocyAgICAgID0gY2VsbHMubWFwIChyID0+IHIubWFwIChzdHJsZW4pKSxcbiAgICAgICAgbWF4V2lkdGhzICAgICAgID0gemlwIChjZWxsV2lkdGhzLCBNYXRoLm1heCksXG5cbiAgICAvKiAgRGVmYXVsdCBjb25maWcgICAgICovXG5cbiAgICAgICAgY2ZnICAgICAgICAgICAgID0gTy5hc3NpZ24gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxpbWl0ZXI6ICcgICcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluQ29sdW1uV2lkdGhzOiBtYXhXaWR0aHMubWFwICh4ID0+IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heFRvdGFsV2lkdGg6IDAgfSwgY2ZnXyksXG5cbiAgICAgICAgZGVsaW1pdGVyTGVuZ3RoID0gc3RybGVuIChjZmcuZGVsaW1pdGVyKSxcblxuICAgIC8qICBQcm9qZWN0IGRlc2lyZWQgY29sdW1uIHdpZHRocywgdGFraW5nIG1heFRvdGFsV2lkdGggYW5kIG1pbkNvbHVtbldpZHRocyBpbiBhY2NvdW50LiAgICAgKi9cblxuICAgICAgICB0b3RhbFdpZHRoICAgICAgPSBtYXhXaWR0aHMucmVkdWNlICgoYSwgYikgPT4gYSArIGIsIDApLFxuICAgICAgICByZWxhdGl2ZVdpZHRocyAgPSBtYXhXaWR0aHMubWFwICh3ID0+IHcgLyB0b3RhbFdpZHRoKSxcbiAgICAgICAgbWF4VG90YWxXaWR0aCAgID0gY2ZnLm1heFRvdGFsV2lkdGggLSAoZGVsaW1pdGVyTGVuZ3RoICogKG1heFdpZHRocy5sZW5ndGggLSAxKSksXG4gICAgICAgIGV4Y2Vzc1dpZHRoICAgICA9IE1hdGgubWF4ICgwLCB0b3RhbFdpZHRoIC0gbWF4VG90YWxXaWR0aCksXG4gICAgICAgIGNvbXB1dGVkV2lkdGhzICA9IHppcCAoW2NmZy5taW5Db2x1bW5XaWR0aHMsIG1heFdpZHRocywgcmVsYXRpdmVXaWR0aHNdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtaW4sIG1heCwgcmVsYXRpdmUpID0+IE1hdGgubWF4IChtaW4sIE1hdGguZmxvb3IgKG1heCAtIGV4Y2Vzc1dpZHRoICogcmVsYXRpdmUpKSksXG5cbiAgICAvKiAgVGhpcyBpcyBob3cgbWFueSBzeW1ib2xzIHdlIHNob3VsZCBwYWQgb3IgY3V0IChwZXIgY29sdW1uKS4gICovXG5cbiAgICAgICAgcmVzdENlbGxXaWR0aHMgID0gY2VsbFdpZHRocy5tYXAgKHdpZHRocyA9PiB6aXAgKFtjb21wdXRlZFdpZHRocywgd2lkdGhzXSwgKGEsIGIpID0+IGEgLSBiKSlcblxuICAgIC8qICBQZXJmb3JtIGZpbmFsIGNvbXBvc2l0aW9uLiAgICovXG5cbiAgICAgICAgcmV0dXJuIHppcCAoW2NlbGxzLCByZXN0Q2VsbFdpZHRoc10sIChhLCBiKSA9PlxuICAgICAgICAgICAgICAgIHppcCAoW2EsIGJdLCAoc3RyLCB3KSA9PiAodyA+PSAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IChjZmcucmlnaHQgPyAoJyAnLnJlcGVhdCAodykgKyBzdHIpIDogKHN0ciArICcgJy5yZXBlYXQgKHcpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAobGltaXQgKHN0ciwgc3RybGVuIChzdHIpICsgdykpKS5qb2luIChjZmcuZGVsaW1pdGVyKSlcbn1cblxuY29uc3QgYXNUYWJsZSA9IGNmZyA9PiBPLmFzc2lnbiAoYXJyID0+IHtcblxuLyogIFByaW50IGFycmF5cyAgKi9cblxuICAgIGlmIChhcnJbMF0gJiYgQXJyYXkuaXNBcnJheSAoYXJyWzBdKSlcbiAgICAgICAgcmV0dXJuIGFzQ29sdW1ucyAoYXJyLCBjZmcpLmpvaW4gKCdcXG4nKVxuXG4vKiAgUHJpbnQgb2JqZWN0cyAgICovXG5cbiAgICBjb25zdCBjb2xOYW1lcyAgICAgICAgPSBbLi4ubmV3IFNldCAoW10uY29uY2F0ICguLi5hcnIubWFwIChPLmtleXMpKSldLFxuICAgICAgICAgIGNvbHVtbnMgICAgICAgICA9IFtjb2xOYW1lcy5tYXAgKGNmZy50aXRsZSksIC4uLmFyci5tYXAgKG8gPT4gY29sTmFtZXMubWFwIChrZXkgPT4gb1trZXldKSldLFxuICAgICAgICAgIGxpbmVzICAgICAgICAgICA9IGFzQ29sdW1ucyAoY29sdW1ucywgY2ZnKVxuXG4gICAgcmV0dXJuIFtsaW5lc1swXSwgY2ZnLmRhc2gucmVwZWF0IChzdHJsZW4gKGxpbmVzWzBdKSksIC4uLmxpbmVzLnNsaWNlICgxKV0uam9pbiAoJ1xcbicpXG5cbn0sIGNmZywge1xuXG4gICAgY29uZmlndXJlOiBuZXdDb25maWcgPT4gYXNUYWJsZSAoTy5hc3NpZ24gKHt9LCBjZmcsIG5ld0NvbmZpZykpLFxufSlcblxubW9kdWxlLmV4cG9ydHMgPSBhc1RhYmxlICh7XG5cbiAgICBtYXhUb3RhbFdpZHRoOiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUixcbiAgICBwcmludDogU3RyaW5nLFxuICAgIHRpdGxlOiBTdHJpbmcsXG4gICAgZGFzaDogJy0nLFxuICAgIHJpZ2h0OiBmYWxzZVxufSkiXX0= |
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42
will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.